Handling data fetching and updating in a Knockout.js application involves integrating your ViewModel with AJAX calls to your server. Here's a step-by-step approach:
1. Setting up the ViewModel
First, create a ViewModel that will hold the data and the methods to fetch and update the data.
viewModel.js
function AppViewModel() {
var self = this;
// Observables for new product input fields
self.newProductName = ko.observable('');
self.newProductPrice = ko.observable('');
// Observable array to store the list of products
self.products = ko.observableArray([]);
// Observables for editing a product
self.editedProductName = ko.observable('');
self.editedProductPrice = ko.observable('');
self.isEditing = ko.observable(false);
self.currentProduct = ko.observable(null);
// Function to add a new product to the list
self.addProduct = function () {
self.products.push({
name: ko.observable(self.newProductName()),
price: ko.observable(self.newProductPrice())
});
self.newProductName('');
self.newProductPrice('');
};
// Function to start editing a product
self.editProduct = function (product) {
self.currentProduct(product);
self.editedProductName(product.name());
self.editedProductPrice(product.price());
self.isEditing(true);
};
// Function to save changes to the edited product
self.saveProduct = function () {
var product = self.currentProduct();
product.name(self.editedProductName());
product.price(self.editedProductPrice());
self.isEditing(false);
};
// Function to delete a product from the list
self.deleteProduct = function (product) {
self.products.remove(product);
};
// Function to cancel editing a product
self.cancelEdit = function () {
self.isEditing(false);
};
}
// Apply Knockout.js bindings to the AppViewModel
ko.applyBindings(new AppViewModel());
2. HTML Markup
Create an HTML markup to display the data and provide a way to add new items.
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Knockout.js CRUD Demo</title>
<!-- Link to Bootstrap CSS for styling -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body>
<div class="container">
<h1>Product Management</h1>
<hr />
<!-- Form to add new products -->
<form class="row g-3" data-bind="submit: addProduct">
<div class="col-12">
<label for="productName" class="fw-bold form-label">Product Name:</label>
<input type="text" class="form-control" placeholder="Product Name" id="productName"
data-bind="value: newProductName, valueUpdate: 'input'" required>
</div>
<div class="col-12">
<label for="productPrice" class="form-label fw-bold">Product Price:</label>
<input type="number" class="form-control" placeholder="Price" id="productPrice"
data-bind="value: newProductPrice, valueUpdate: 'input'" required>
</div>
<div class="col-12">
<button type="submit" class="btn btn-outline-primary">Add Product</button>
</div>
</form>
<hr />
<!-- Table to display products -->
<div class="table-responsive" data-bind="if: products().length > 0">
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th>Product Name</th>
<th>Product Price</th>
<th>Actions</th>
</tr>
</thead>
<tbody data-bind="foreach: products">
<tr>
<th scope="col" data-bind="text: ($index() + 1)"></th>
<td><span data-bind="text: name"></span></td>
<td><span data-bind="text: price"></span></td>
<td class="d-flex">
<button class="btn btn-link text-primary"
data-bind="click: $parent.editProduct">Edit</button>
<button class="btn btn-link text-danger"
data-bind="click: $parent.deleteProduct">Delete</button>
</td>
</tr>
</tbody>
</table>
</div>
<!-- Section for editing products -->
<div class="my-3" data-bind="if: isEditing">
<h2>Edit Product</h2>
<form class="row g-3" data-bind="submit: saveProduct">
<div class="col-12">
<label for="editProductName" class="form-label fw-bold">Product Name:</label>
<input type="text" id="editProductName" class="form-control" placeholder="Product Name"
data-bind="value: editedProductName, valueUpdate: 'input'" required>
</div>
<div class="col-12">
<label for="editProductPrice" class="form-label fw-bold">Product Price:</label>
<input type="number" id="editProductPrice" class="form-control" placeholder="Price"
data-bind="value: editedProductPrice, valueUpdate: 'input'" required>
</div>
<div class="col-12">
<button type="submit" class="btn btn-outline-primary">Save Changes</button>
<button type="button" data-bind="click: cancelEdit" class="btn btn-secondary">Cancel</button>
</div>
</form>
</div>
</div>
<!-- Link to Knockout.js library for MVVM pattern support -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.5.1/knockout-latest.min.js"
integrity="sha512-vs7+jbztHoMto5Yd/yinM4/y2DOkPLt0fATcN+j+G4ANY2z4faIzZIOMkpBmWdcxt+596FemCh9M18NUJTZwvw=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="path/to/your/viewModel.js"></script>
</body>
</html>
Explanation
- ViewModel: The
AppViewModel
contains observables for data (items
) and user input (newItem
). It also has methods for fetching and updating data (fetchData
andaddItem
). - Fetching Data:
fetchData
makes an AJAX GET request to the server to fetch items. On success, it updates theitems
observable array. - Adding Data:
addItem
makes an AJAX POST request to add a new item. On success, it updates theitems
observable array with the new item. - HTML Binding: The HTML uses Knockout.js bindings to display the list of items and bind input fields and buttons to the ViewModel.
Output-
Read more
Knockout.js: Building Dynamic Web Applications
Retrieve Data from RESTFul API and add Paging in
How to read JSON data using Knockout?
Leave Comment